package com.contain.linkedlist;

import java.util.LinkedHashMap;
import java.util.Map;

/**我们可以看到LinkedHashMap有一个成员变量accessOrder，该成员变量记录了是否需要按访问顺序排序，它提供了一个构造器可以自己指定accessOrder的值。
 * 每次调用get方法获取元素式都会调用e.recordAccess(this)，该方法会将当前结点移到双向链表的尾部。现在我们知道了如果accessOrder为true那么每次get元素后都会把这个元素挪到双向链表的尾部。
 * 这一步的目的是区别出最常使用的元素和不常使用的元素，经常使用的元素放到尾部，不常使用的元素放到头部。
 * 我们再回到上面的代码中看到每次调用addEntry方法时都会判断是否需要删除最老的元素。判断的逻辑是removeEldestEntry实现的，该方法被设计成由子类进行覆盖并重写里面的逻辑。
 * 注意，由于最近被访问的结点都被挪动到双向链表的尾部，所以这里是从双向链表头部取出最老的结点进行删除。
 * @author DELL
 *
 * @param <K>
 * @param <V>
 */
public class LRUMap<K, V> extends LinkedHashMap<K, V> {

    private int capacity;

    LRUMap(int capacity) {
        //调用父类构造器, 设置为按访问顺序排序
        super(capacity, 1f, true);
        this.capacity = capacity;
    }

    @Override
    public boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        //当键值对大于等于哈希表容量时
        return this.size() >= capacity;
    }

    public static void main(String[] args) {
        LRUMap<Integer, String> map = new LRUMap<Integer, String>(4);
        map.put(1, "a");
        map.put(2, "b");
        map.put(3, "c");
        System.out.println("原始集合:" + map);
        String s = map.get(2);
        System.out.println("获取元素:" + map);
        map.put(4, "d");
        System.out.println("插入之后:" + map);
    }

}